var http = require('http')

var port = process.env.PORT || '3000'

const Koa = require('koa')
const app = new Koa()
const views = require('koa-views')
const json = require('koa-json')
const cors = require('koa2-cors')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const koaBody = require('koa-body')
const log4js = require('./utils/log4j')
const koajwt = require('koa-jwt')
const router = require('koa-router')()
const users = require('./routes/users')
const menus = require('./routes/menus')
const roles = require('./routes/roles')
const depts = require('./routes/depts')
const leaves = require('./routes/leaves')
const single = require('./routes/single')
const logs = require('./routes/logs')
const util = require('./utils/util')
const socket = require('./utils/socket')

// error handler
onerror(app)
// 数据库连接
require('./config/db')
// middlewares

app.use(
  koaBody({
    multipart: true, // 支持文件上传
    formidable: {
      maxFieldsSize: 10 * 1024 * 1024, // 最大文件为10兆
      multipart: true, // 是否支持 multipart-formdate 的表单
    },
  })
)
app.use(
  bodyparser({
    enableTypes: ['json', 'form', 'text'],
  })
)
app.use(json())
app.use(cors())
app.use(require('koa-static')(__dirname + '/public'))
app.use(
  views(__dirname + '/views', {
    extension: 'ejs',
  })
)

// logger
app.use(async (ctx, next) => {
  await next().catch((err) => {
    if (err.status == 401) {
      ;(ctx.status = 200),
        (ctx.body = util.fail('Toke认证失败', util.CODE.AUTH_ERROR))
    }
  })
})

app.use(
  koajwt({ secret: 'abizuis' }).unless({
    path: [/^\/api\/users\/login/, /^\/api\/single\/upload/, /^\/socket\.io/],
  })
)

// 路由
app.use(router.routes(), router.allowedMethods())
router.prefix('/api')

router.use(depts.routes(), depts.allowedMethods())
router.use(users.routes(), users.allowedMethods())
router.use(menus.routes(), menus.allowedMethods())
router.use(roles.routes(), roles.allowedMethods())
router.use(leaves.routes(), leaves.allowedMethods())
router.use(single.routes(), single.allowedMethods())
router.use(logs.routes(), logs.allowedMethods())
// 报错拦截
app.on('error', (err, ctx) => {
  log4js.error(`${err.stack}`)
})

var server = http.createServer(app.callback())
server.listen(port)
server.on('error', onError)
server.on('listening', onListening)

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error
  }

  var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges')
      process.exit(1)
      break
    case 'EADDRINUSE':
      console.error(bind + ' is already in use')
      process.exit(1)
      break
    default:
      throw error
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address()
  var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port
  console.log('Listening on ' + bind)
  socket.init(server)
}
